Unit Main;

interface

uses
  Windows,
  Messages,
  SysUtils,
  DirectDraw,
  Engine,
  Dinput,
  Debug,
  PicFile,
  Sound,
  Math,
  ini,
  UI,
  graphics,
  Head,
  Event;

type
  TGame = class
    GameInput: Tinput;
    GameEngine: TEngine;
    GamePicFile: TpicFile;
    GameSound: Tsound;
    GameIni: Pini;
    GameUI: TUI;
    GameEvent: TEvent;
    PauseTime: integer;
    function run: integer;
    function Initial: integer;
    function GetNow: integer;
    procedure ShutDown;
    procedure Update;
    procedure UpdateSurface;
    procedure UpdateWithoutSurface;
    procedure PlayMovie(Filename: String);
  end;

  PGame = ^TGame;

const
  GameCaption = '永远的剑侠情缘';

implementation

uses
  Script;

 //游戏运行
function TGame.run: integer;
var
  Ix, Iy: integer;
  amp: msg;
  nowms, nextms, frame, FPS: integer;
  time1, time2: integer;
  s: String;
begin

  GameDebug.AddDebugInfo('汉字');

  result := 2;
  if Initial <> 0 then
    exit;
  GameDebug.AddDebugInfo('Game Run!');

  PlayMovie('1.avi');

  if GameSound.LoadSoundFromFile('Wave.mp3', music, 0) = 0 then
    GameSound.PlayMusic
  else
    GameSound.StopMusic;

  FPS := 0;
  Frame := 0;

  nowms := GameEngine.getnow;
  nextms := nowms + 1000;
  Gamedebug.AddDebugInfo(s);
  //游戏的主循环
  while Gamerun do
  begin

    (************---计算FPS---************)
    //帧数加1
    inc(frame);
    nowms := GameEngine.getnow;
    if nowms >= nextms then
    begin
      if nowms = nextms then
        FPS := Frame
      else
        FPS := Frame - 1;
      nextms := nowms + 1000;
      GameDebug.AddDebugInfo('FPS:' + inttostr(FPS));
      FPS := min(FPS, GameEngine.MaxFPS);
      frame := 0;

    end;
    (*************************************)


    //time1:= nows;
    if (PeekMessage(amp, GameEngine.GameWindow, 0 , 0 , PM_REMOVE)) then
    begin
      paused := true;
      // 消息转换
      TranslateMessage(amp);
      DispatchMessage(amp);
    end;
    if Paused then
    begin
      time2 := GameEngine.Getnow;
      PauseTime := time2 - {time1}nowms + PauseTime;
      paused := false;
      //if time2-nowms > 0 then
        //GameDebug.AddDebugInfo('Pause Time:'+inttostr(time2-nowms));
    end;

    GameInput.GetKeyState;
    if GameEngine.CanContinue then
    begin
      UpdateWithoutSurface;
      if GameEngine.ScreenbufLock = 0 then
      begin

        for Ix:= 0 to GameEngine.window_W - 1 do
          for iy := 0 to GameEngine.window_H - 1 do
          begin
            GameEngine.putbufpixel(ix, iy, nowms shr 4);
          end;

        GameEngine.BufTextOut('FPS:' + inttostr(FPS), 0, 0, 15, $FFFFFF);

        UpdateSurface;

      end;
    end;

  end;

  result := 0;
end;

function TGame.GetNow: integer;
begin
  result := GameEngine.Getnow - PauseTime;
end;

procedure TGame.Update;
begin
  UpdateWithoutSurface;
  UpdateSurface;
end;

procedure TGame.UpdateSurface;
begin
  if GameEngine.UpdateCursor(GameInput.MouseX, GameInput.MouseY) then
    GameEngine.bufTextOut('鼠标在窗体外:'+ inttostr(GameInput.MouseX) + ','+ inttostr(GameInput.MouseY), 60, 0, 15, $FFFFFF)
  else
    GameEngine.bufTextOut('鼠标在窗体内:'+ inttostr(GameInput.MouseX) + ','+ inttostr(GameInput.MouseY), 60, 0, 15, $FFFFFF);
  if not GameEngine.CursorShow then
    GameUI.DrawMouse(GameInput.MouseX, GameInput.MouseY);
  GameEngine.Update;
end;

procedure TGame.UpdateWithoutSurface;
begin
  //声音在未激活窗体时静音
  if not GameSound.Soundsustained then
  begin
    if Engine_Music_Control = EMC_restore then
    begin
      GameDebug.AddDebugInfo('Sound Restore');
      GameSound.Restore;
      Engine_Music_Control := EMC_none;
    end
    else if Engine_Music_Control = EMC_silent then
    begin
      GameDebug.AddDebugInfo('Silent');
      GameSound.Silent;
      Engine_Music_Control := EMC_none;
    end
  end;
  GameSound.update;
end;

//游戏初始化
function TGame.Initial: integer;
begin

  //初始化引擎
  GameDebug.AddDebugInfo('Initial Game Engine!');
  GameEngine := TEngine.create(WindowMode, WindowWidth, WindowHeight, GameCaption, false, GameFPS);
  if GameEngine.Initial  <> 0 then
  begin
    GameDebug.AddDebugInfo('Initial Game Engine Fail!');
    result := 2;
    exit;
  end;

  GameDebug.AddDebugInfo('Initial Game Input!');
  GameInput := Tinput.Create;
  if GameInput.Initial(GameEngine.GameWindow, WindowMode) <> 0 then
  begin
    GameDebug.AddDebugInfo('Initial Game Input Fail!');
    result := 3;
    exit;
  end;

  GamePicFile := TpicFile.Create;
  GamePicFile.PicEngine := @GameEngine;

  GameDebug.AddDebugInfo('Initial Game Sound!');
  GameSound := Tsound.create;
  if Gamesound.initial <> 0 then
  begin
    GameDebug.AddDebugInfo('Initial Game Sound Fail!');
    result := 4;
    exit;
  end;

  GameDebug.AddDebugInfo('Initial Game UI!');
  GameUI := TUI.Create;
  if GameUI.Initial(@GameEngine) <> 0 then
  begin
    GameDebug.AddDebugInfo('Initial Game UI Fail!');
    result := 5;
    exit;
  end;

  GameIni := @CINI;

  GameEvent := TEvent.Create(@self.GameEngine);

  //初始化脚本
  GameScript := TScript.Create(@self);

  Gamerun := true;
  Paused := false;
  PauseTime := 0;

  result := 0;
end;

procedure TGame.ShutDown;
begin
  //游戏释放资源
  //释放游戏底层引擎资源(DirectDraw等)
  GameDebug.AddDebugInfo('Release Game Resource!');
  gamerun := false;

  if GamePicFile <> nil then
  begin
    GamePicFile.Destroy;
    GameDebug.AddDebugInfo('PicFile Freed!');
  end;
  if GameInput <> nil then
  begin
    GameInput.Destroy;
    GameDebug.AddDebugInfo('Game Input Freed!');
  end;
  if GameSound <> nil then
  begin
    GameSound.Destroy;
    GameDebug.AddDebugInfo('Game Sound Freed!');
  end;
  if GameUI <> nil then
  begin
    GameUI.Destroy;
    GameDebug.AddDebugInfo('Game UI Freed!');
  end;
  if GameEvent <> nil then
  begin
    GameEvent.Destroy;
  end;

  //释放脚本
  if GameScript <> nil then
  begin
    GameScript.Destroy;
  end;

  if GameEngine <> nil then
  begin
    GameEngine.Release;
  end;
end;

procedure TGame.PlayMovie(Filename: String);
begin
  GameSound.Silent;
  GameEngine.PlayMovie(Filename);
  GameSound.Restore;
end;

end.
